package com.rdgzs.framework.utilsTools;

import java.beans.PropertyDescriptor;
import java.lang.reflect.Method;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.StringTokenizer;

import javax.sql.rowset.CachedRowSet;

import org.apache.commons.beanutils.PropertyUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class ObjectTransformUtils {

	private static Logger logger = LoggerFactory.getLogger(ObjectTransformUtils.class);

	public ObjectTransformUtils() {
	}

	public static List convertResult2List(ResultSet rs) throws SQLException {
		List list = new ArrayList();
		ResultSetMetaData md = rs.getMetaData();
		int columnCount = md.getColumnCount();
		while (rs.next()) {
			Map rowData = new HashMap();
			for (int i = 1; i <= columnCount; i++) {
				rowData.put(md.getColumnName(i), rs.getObject(i));
			}
			list.add(rowData);
		}
		return list;
	}

	public static List rowset2List(CachedRowSet rs) throws Exception {
		List result = new ArrayList();
		try {
			rs.beforeFirst();
			ObjectTransformUtils util = new ObjectTransformUtils();
			Map row;
			for (; rs.next(); result.add(row)) {
				row = new HashMap();
				row = util.rowset2Map(rs, true, false);
			}

		} catch (Exception ex) {
			logger.error(ex.getLocalizedMessage());
			throw new Exception(ex);
		}
		return result;
	}

	public static List rowset2List(CachedRowSet rs, boolean isKey) throws Exception {
		List result = new ArrayList();
		try {
			rs.beforeFirst();
			ObjectTransformUtils util = new ObjectTransformUtils();
			Map row;
			for (; rs.next(); result.add(row)) {
				row = new HashMap();
				row = util.rowset2Map(rs, isKey, false);
			}

		} catch (SQLException ex) {
			logger.error(ex.getLocalizedMessage());
			throw new Exception(ex);
		}
		return result;
	}

	public static List rowset2List(CachedRowSet rs, boolean isKey, boolean isBig)
			throws Exception {
		List result = new ArrayList();
		try {
			rs.beforeFirst();
			ObjectTransformUtils util = new ObjectTransformUtils();
			Map row;
			for (; rs.next(); result.add(row)) {
				row = new HashMap();
				row = util.rowset2Map(rs, isKey, isBig);
			}

		} catch (SQLException ex) {
			logger.error(ex.getLocalizedMessage());
			throw new Exception(ex);
		}
		return result;
	}

	public static Map rowset2Map(CachedRowSet rs) throws Exception {
		String columnTypeName = "";
		String colummName = "";
		Map row = new HashMap();
		try {
			rs.beforeFirst();
			ObjectTransformUtils util = new ObjectTransformUtils();
			if (rs.next())
				row = util.rowset2Map(rs, true, false);
		} catch (SQLException ex) {
			logger.error(ex.getMessage(), ex);
			throw new Exception(ex);
		}
		return row;
	}

	protected Map rowset2Map(CachedRowSet rs, boolean isKey, boolean isBig) throws Exception {
		String columnTypeName = "";
		String colummName = "";
		String key = "";
		int precision = 0;
		int scale = 0;
		Map row = new HashMap();
		try {
			ResultSetMetaData metaData = rs.getMetaData();
			row = new HashMap();
			for (int i = 1; i <= metaData.getColumnCount(); i++) {
				columnTypeName = metaData.getColumnTypeName(i);
				colummName = metaData.getColumnName(i);
				key = colummName;
				if ("timestamp".equalsIgnoreCase(columnTypeName)) {
					java.sql.Timestamp data = rs.getTimestamp(colummName);
					row.put(key, DateTimeUtils.convSqlTimestampToUtilCalendar(data));
					continue;
				}
				if ("date".equalsIgnoreCase(columnTypeName)) {
					java.sql.Timestamp data = rs.getTimestamp(colummName);
					row.put(key, DateTimeUtils.convSqlTimestampToUtilCalendar(data));
					continue;
				}
				if ("number".equalsIgnoreCase(columnTypeName)) {
					if (isBig) {
						Object data = rs.getBigDecimal(colummName);
						row.put(key, data);
						continue;
					}
					precision = metaData.getPrecision(i);
					scale = metaData.getScale(i);
					String num = StringUtils.stringTrim(rs.getString(colummName));
					if ("".equals(num))
						num = "0";
					if (precision <= 0) {
						row.put(key, num);
						continue;
					}
					if (scale > 0) {
						Object data = new Double(num);
						row.put(key, data);
						continue;
					}
					if (precision > 8) {
						Object data = new Long(num);
						row.put(key, data);
					} else {
						Object data = new Integer(num);
						row.put(key, data);
					}
				} else {
					Object data = rs.getObject(colummName);
					row.put(key, data);
				}
			}

		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
			throw new Exception(ex);
		}

		return row;
	}

	public static Map convertList2Map(List table, String keyFieldName, boolean isDBKey) {
		Map map = new HashMap();
		List keys = new ArrayList();
		if (isDBKey)
			keyFieldName = keyFieldName.toUpperCase();
		if (keyFieldName.indexOf(",") < 0) {
			keys.add(keyFieldName);
		} else {
			for (StringTokenizer st = new StringTokenizer(keyFieldName, ","); st
					.hasMoreElements(); keys.add(st.nextElement()))
				;
		}
		StringBuffer key = new StringBuffer();
		String keyStr = null;
		Map row = null;
		for (int i = 0; i < table.size(); i++) {
			key.delete(0, key.length());
			row = (Map) table.get(i);
			for (int keyIndex = 0; keyIndex < keys.size(); keyIndex++) {
				key.append(row.get(keys.get(keyIndex)));
				key.append(",");
			}

			keyStr = key.toString();
			if (keyStr.endsWith(","))
				keyStr = keyStr.substring(0, keyStr.length() - 1);
			map.put(keyStr, row);
		}

		return map;
	}

	public static void copyProperties(Object dest, Object orig) {
		copyProperties(dest, orig, null);
	}

	public static void copyProperties(Object dest, Object orig, String ignores[]) {
		if (dest == null || orig == null) {
			return;
		}
		PropertyDescriptor destDesc[] = PropertyUtils.getPropertyDescriptors(dest);
		try {
			for (int i = 0; i < destDesc.length; i++) {
				if (ignores!=null && contains(ignores, destDesc[i].getName())) {
					continue;
				}
				Class destType = destDesc[i].getPropertyType();
				Class origType = PropertyUtils.getPropertyType(orig, destDesc[i].getName());
				if (destType != null && destType.equals(origType)
						&& !destType.equals(java.lang.Class.class)
						&& !(java.util.Collection.class).isAssignableFrom(origType)) {
					Object value = PropertyUtils.getProperty(orig, destDesc[i].getName());
					PropertyUtils.setProperty(dest, destDesc[i].getName(), value);
				}
			}

		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}

	private static boolean contains(String ignores[], String name) {
		boolean ignored = false;
		int j = 0;
		do {
			if (ignores == null || j >= ignores.length)
				break;
			if (ignores[j].equals(name)) {
				ignored = true;
				break;
			}
			j++;
		} while (true);
		return ignored;
	}

}
